#!/usr/bin/env python
import types

def fs_output(header_list, rowdata_list, fobj, field_separator='\s'):
    '''
    prints the data in a field-separated table with headers.
    '''

    header_str = field_separator.join(header_list)

    print >>fobj, header_str

    for item in rowdata_list:

        row_str = ''

        for attr in header_list:

            data = item[ attr ]

            if data is None:
                row_str += 'N/A' + field_separator
            else:
                if type( data ) in [ types.IntType, types.LongType, types.FloatType ]:
                    row_str += '%d%s' % ( int(data), field_separator )
                else:
                    row_str += '%s%s' % ( data, field_separator )

        print >>fobj, row_str
    
    fobj.flush()

def csv_output(header_list, rowdata_list, fobj):
    '''
    prints the data in a CSV format table with headers in first line.
    '''
    fs_output(header_list, rowdata_list, fobj, field_separator=',')

def tab_output(header_list, rowdata_list, fobj):
    '''
    prints the data in a TAB separated table with headers.
    '''
    fs_output(header_list, rowdata_list, fobj, field_separator='\t')

def table_output(title, header_list, rowdata_list, fobj):
    '''
    prints the data in a well-formated table with title and headers.
    '''

    # scan throuhg all attributes to determin the size of each row
    row_size = {}
    for attr in header_list:
        row_size[attr] = len(attr) + 2

    for item in rowdata_list:

        for attr in header_list:

            if item[ attr ] is None:
                size = 5
            else:
                size = len( repr(item[ attr ]) ) + 2

            if row_size[attr] < size:
                row_size[attr] = size


    # formating the table header
    header_str = ''
    for attr in header_list:
        header_str += attr.center( row_size[attr] )

    if title:
        print >>fobj, '[ %s ]' % title

    if len(rowdata_list) > 0:
        print >>fobj, '-'*sum(row_size.values())
        print >>fobj, header_str
        print >>fobj, '-'*sum(row_size.values())

    # formating the table contents
    for item in rowdata_list:

        row_str = ''

        for attr in header_list:
            if item[ attr ] is None:
                row_str += 'N/A'.center( row_size[attr] )
            else:
                if type( item[ attr ] ) in [ types.IntType, types.LongType, types.FloatType ]:
                    row_str += repr( item[ attr ] ).rjust( row_size[attr] )
                else:
                    row_str += item[ attr ].center( row_size[attr] )

        print >>fobj, row_str

    if len(rowdata_list) > 0:
        print >>fobj, '-'*sum(row_size.values())

    ## flush out the data to the file object
    fobj.flush()